package com.demo.algorithm.demo5;

import java.util.Date;
import java.util.concurrent.*;

/**
 * <p>
 * </p>
 *
 * @author yanyg
 * @date 2024/2/19 17:09
 */
public class ThreadPoolExecutorTest {

    public static void main(String[] args) {
        // 创建一个固定大小的线程池，可控制并发的线程数，超出的线程会在队列中等待
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 创建单个线程数的线程池，它可以保证先进先出的执行顺序
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
        // 创建一个可缓存的线程池，若线程数超过处理所需，缓存一段时间后会回收多余的线程，若线程数不够，则新建线程
        ExecutorService executorService1 = Executors.newCachedThreadPool();
        // 创建一个可以延时执行、周期执行的线程池(单线程)
        ScheduledExecutorService scheduledExecutorService1 = Executors.newSingleThreadScheduledExecutor();
        // 创建一个可以延时执行、周期执行的线程池（指定核心线程池）
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        // scheduleAtFixedRate：是以period为间隔来执行任务的，如果任务执行时间小于period，则上次任务执行完成后会间隔period后再去执行下一次任务；
        // 但如果任务执行时间大于period，则上次任务执行完毕后会不间隔的立即开始下次任务
        // 而scheduleWithFixedDelay 是不管任务执行多久，都会等上一次任务执行完毕后再延迟delay后去执行下次任务
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            try {
                Thread.sleep(1000L);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("scheduleAtFixedRate:" + new Date());
        }, 5, 2, TimeUnit.SECONDS);

        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            try {
                Thread.sleep(1000L);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("scheduleAtFixedRate:" + new Date());
        }, 5, 2, TimeUnit.SECONDS);


        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
        // 执行任务
        for (int i = 0; i < 10; i++) {
            final int index = i;
            threadPool.execute(() -> {
                System.out.println(index + " 被执行,线程名:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

    }
}

